﻿using Abp.Application.Services.Dto;
using Abp.Authorization;
using Abp.Domain.Repositories;
using Abp.Linq.Extensions;
using Abp.UI;
using Microsoft.EntityFrameworkCore;
using Partner.Surround.Authorization;
using Partner.Surround.Core.DataDictionaries.Dto;
using Partner.Surround.Notifications;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Partner.Surround.Core.DataDictionaries
{
    public class DataDictionaryAppService : SurroundAppServiceBase, IDataDictionaryAppService
    {
        #region 初始化
        private readonly IRepository<DataDictionary, long> _dataDictionaryRepository;
        private readonly IAppNotifier _appNotifier;

        public DataDictionaryAppService(IRepository<DataDictionary, long> dataDictionaryRepository,
            IAppNotifier appNotifier)
        {
            _dataDictionaryRepository = dataDictionaryRepository;
            _appNotifier = appNotifier;
        }
        #endregion

        public async Task<DataDictionaryEditDto> GetDataDictionaryForEditAsync(NullableIdDto<long> input)
        {
            var dataDictionaryEditDto = new DataDictionaryEditDto();
            if (input.Id.HasValue)
            {
                var dataDictionary = await _dataDictionaryRepository.GetAsync(input.Id.Value);
                dataDictionaryEditDto = ObjectMapper.Map<DataDictionaryEditDto>(dataDictionary);
            }

            return dataDictionaryEditDto;
        }

        public async Task CreateOrUpdateDataDictionaryAsync(CreateOrUpdateDataDictionaryInput input)
        {
            if (input.DataDictionary.Id.HasValue)
                await UpdateDataDictionaryAsync(input);
            else
                await CreateDataDictionaryAsync(input);
        }

        [AbpAuthorize(PermissionNames.Pages_Core_DataDictionary_Create)]
        private async Task CreateDataDictionaryAsync(CreateOrUpdateDataDictionaryInput input)
        {
            var existedDataDictionary = await _dataDictionaryRepository.GetAll().Where(d => d.TypeName == input.DataDictionary.TypeName).FirstOrDefaultAsync();

            if (existedDataDictionary != null)
            {
                throw new UserFriendlyException(L("该字典类型已存在，无法添加"));
            }

            var dataDictionary = ObjectMapper.Map<DataDictionary>(input.DataDictionary);
            await _dataDictionaryRepository.InsertAsync(dataDictionary);

            //模拟测试消息通知
            await _appNotifier.NewTaskAsync("字典类型已完成添加，可以开始使用了");
        }

        [AbpAuthorize(PermissionNames.Pages_Core_DataDictionary_Edit)]
        private async Task UpdateDataDictionaryAsync(CreateOrUpdateDataDictionaryInput input)
        {
            if (!input.DataDictionary.Id.HasValue || input.DataDictionary.Id.Value <= 0)
            {
                throw new UserFriendlyException(L("操作异常，数据有误"));
            }

            var dataDictionary = await _dataDictionaryRepository.GetAsync(input.DataDictionary.Id.Value);

            var existedDataDictionary = await _dataDictionaryRepository.GetAll().Where(d => d.TypeName == input.DataDictionary.TypeName).FirstOrDefaultAsync();
            if (existedDataDictionary != null && existedDataDictionary.Id != dataDictionary.Id)
            {
                throw new UserFriendlyException(L("该字典类型已存在，无法更新"));
            }

            ObjectMapper.Map(input.DataDictionary, dataDictionary);

            await _dataDictionaryRepository.UpdateAsync(dataDictionary);
        }

        [AbpAuthorize(PermissionNames.Pages_Core_DataDictionary_Delete)]
        public async Task DeleteDataDictionaryAsync(List<EntityDto<long>> inputs)
        {
            foreach (var input in inputs)
            {
                await _dataDictionaryRepository.DeleteAsync(input.Id);
            }
        }

        public async Task<ListResultDto<DataDictionaryListDto>> GetDataDictionaryListByTypeNamesAsync(GetDataDictionaryListByTypeNamesInput input)
        {
            var items = await _dataDictionaryRepository.GetAll()
                .WhereIf(input.TypeNames != null && input.TypeNames.Count() > 0, d => input.TypeNames.Contains(d.TypeName))
                .Include(d => d.DataDictionaryItem)
                .ToListAsync();

            return new ListResultDto<DataDictionaryListDto>(ObjectMapper.Map<List<DataDictionaryListDto>>(items));
        }

        public async Task<ListResultDto<DataDictionaryListDto>> GetAllDataDictionaryListAsync()
        {
            var items = await _dataDictionaryRepository.GetAllListAsync();
            return new ListResultDto<DataDictionaryListDto>(ObjectMapper.Map<List<DataDictionaryListDto>>(items));
        }
    }
}
